package org.cying.main.controller;

import cn.hutool.http.HttpStatus;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.cying.main.domain.*;
import org.cying.main.feign.TaskFeignDept;
import org.cying.main.feign.TaskFeignStudent;
import org.cying.main.handler.GlobalFlowHandler;
import org.cying.main.handler.TaskFlowHandler;
import org.cying.main.service.TaskService;
import org.cying.main.util.RsaUtil;
import org.cying.main.util.TaskUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;

/**
 * Task Server 控制类
 * @author Cying
 */
@Slf4j
@RefreshScope
@RestController
@RequestMapping(value = "/task")
public class TaskController {
    
    @Resource
    private TaskService service;

    @Resource
    private TaskFeignDept dSer;

    @Resource
    private TaskFeignStudent sSer;

    @Value("${cying.private-key}")
    private String privateKey;

    /**
     * 将任务置为截止
     * @param tid 任务号
     * @return 更新结果
     */
    @PatchMapping(value = "/alter/close")
    @SentinelResource(
            value = "alter-close",
            blockHandlerClass = GlobalFlowHandler.class,
            blockHandler = "flowHandler_s"
    )
    public SampleResult<Object> alterClose(
            @RequestParam(value = "tid", required = true) String tid
    ) {
        return service.setClose(tid) == 1
                ? new SampleResult<>("/task/alter/close", HttpStatus.HTTP_OK)
                : new SampleResult<>("/task/alter/close", HttpStatus.HTTP_NOT_ACCEPTABLE);
    }

    /**
     * 创建新的任务
     * @param subject 主题
     * @param describe 描述
     * @param issuer 发布人
     * @param deadLine 截止时间
     * @param type 类型
     * @param deptList 部门列表
     * @param groupList 小组列表
     * @param stuList 学生列表
     * @param imgList 图列表
     * @return 创建结果
     */
    @PostMapping(value = "/create/record")
    @SentinelResource(
            value = "create-record",
            blockHandlerClass = TaskFlowHandler.class,
            blockHandler = "createNewTaskHandler"
    )
    public SampleResult<Object> createRecord(
            @RequestParam(value = "subject",    required = true) String subject,
            @RequestParam(value = "describe",   required = true) String describe,
            @RequestParam(value = "issuer",     required = true) String issuer,
            @RequestParam(value = "deadLine",   required = true) String deadLine,
            @RequestParam(value = "type",       required = true) Integer type,
            @RequestParam(value = "deptList",   required = false) List<String> deptList,
            @RequestParam(value = "groupList",  required = false) List<String> groupList,
            @RequestParam(value = "stuList",    required = false) List<String> stuList,
            @RequestParam(value = "imgList",    required = false) List<String> imgList
    ) {
        deptList.forEach(System.out::println);
        issuer = RsaUtil.dencrypt(issuer, privateKey);
        subject = RsaUtil.dencrypt(subject, privateKey);
        deadLine = RsaUtil.dencrypt(deadLine, privateKey);
        System.out.println();
        boolean flag = service.issueTask(subject, describe, Long.valueOf(issuer), deadLine, type, deptList, groupList, stuList, imgList);
        return flag
            ? new SampleResult<>("/task/create-task", 200, null, "创建成功")
            : new SampleResult<>("/task/create-task", 200, null, "创建失败");
    }

    @DeleteMapping(value = "/delete/task")
    public SampleResult<Boolean> deleteTask(
            @RequestParam(value = "tid", required = false) String tid,
            @RequestParam(value = "department", required = false) String department,
            @RequestParam(value = "group", required = false) String group,
            @RequestParam(value = "sid", required = false) String sid
    ) {
        Long SID = RsaUtil.parseSid(sid, privateKey);
        return service.deleteTask(tid, SID, department, group)
                ? new SampleResult<>("/task/delete/task", HttpStatus.HTTP_OK, true, "删除成功")
                : new SampleResult<>("/task/delete/task", HttpStatus.HTTP_NOT_ACCEPTABLE, false, "删除失败");

    }

    @GetMapping(value = "/get/commited")
    public SampleResult<List<CommitContent>> getCommited(
            @RequestParam("tid") String tid,
            @RequestParam("department") String department,
            @RequestParam("group") String group
    ) {
        List students = sSer.getByDept(department, group).getData();
        List<CommitContent> result = new ArrayList<>(students.size());
        Iterator iterator = students.iterator();
        while (iterator.hasNext()) {
            String json = JSON.toJSONString(iterator.next());
            Student student = JSON.parseObject(json, Student.class);
            CommitContent commited = service.getCommited(student.getSid(), tid);
            if (commited == null) {
                iterator.remove();
            } else {
                commited.combile(student);
                result.add(commited);
            }
        }
        return new SampleResult<>("/task/get/commited", HttpStatus.HTTP_OK, result);
    }

    /**
     * 获取某学生的任务完成情况
     * @param sid 学号
     * @param start 起始日期
     * @param end 结束日期
     * @return 查询结果
     */
    @GetMapping(value = "/get/statistics")
    @SentinelResource(
            value = "get-status",
            blockHandlerClass = TaskFlowHandler.class,
            blockHandler = "getTaskStatusHandler"
    )
    public SampleResult<Map<String, Integer>> getStatistics(
            @RequestParam(value = "sid", required = true) String sid,
            @RequestParam(value = "start", required = true) String start,
            @RequestParam(value = "end", required = true) String end
    ) {
        Long id = RsaUtil.parseSid(sid, privateKey);
        Map<String, Integer> map = new HashMap<>();
        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("sid", id);
        reqMap.put("start", start);
        reqMap.put("end", end);
        map.put("total", service.getTaskTotal(reqMap));
        map.put("finished", service.getTaskFinish(reqMap));
        map.put("unfinish", service.getTaskUnFinish(reqMap));
        map.put("prefinish", service.getTaskPreFinish(reqMap));
        return new SampleResult<>("Status", 200, map);
    }
    
    /**
     * 查询任务
     * 查询到任务列表之后对其进行遍历，如果 sid 不为 null，说明只查询个人
     *   此时，若且某个任务的 type 为 2，则说明该任务就是个人
     * @param sid 学号
     * @param dept 部门
     * @param close 是否截止
     * @param complete 是否完成
     * @param issuer 发布人
     * @param type 类型
     * @return 查询结果
     */
    @GetMapping("/get/task")
    @SentinelResource(
            value = "get-task",
            blockHandlerClass = TaskFlowHandler.class,
            blockHandler = "queryTaskHandler"
    )
    public SampleResult<List<Task>> getTasks(
            @RequestParam(value = "sid", required = false) String sid,
            @RequestParam(value = "dept", required = false) String dept,
            @RequestParam(value = "close", required = false) Integer close,
            @RequestParam(value = "complete", required = false) Integer complete,
            @RequestParam(value = "issuer", required = false) String issuer,
            @RequestParam(value = "type", required = false) Integer type
    ) {
        Long SID = sid == null ? null : RsaUtil.parseSid(sid, privateKey);
        Long ISSUER = issuer == null ? null : RsaUtil.parseSid(issuer, privateKey);
        List<Task> tasks = service.getTask(SID, dept, close, ISSUER, type);
        System.out.println(tasks);
        Student student = SID != null ? sSer.getBySid(sid, null).getData().get(0) : null;
        TaskUtils.departmentHandler(tasks, SID, complete, student, dSer, service);
        return new SampleResult<>("/task/get/task", HttpStatus.HTTP_OK, tasks);
    }

    /**
     * 提交某个任务
     * @param tid 任务号
     * @param sid 学号
     * @param content 内容
     * @param imgs 图片列表
     * @return 提交结果
     */
    @PostMapping(value = "/post/task")
    @SentinelResource(
            value = "post-task",
            blockHandlerClass = TaskFlowHandler.class,
            blockHandler = "commitTaskHandler"
    )
    public SampleResult<Object> postTask(
            @RequestParam(value = "tid", required = true) String tid,
            @RequestParam(value = "sid", required = true) String sid,
            @RequestParam(value = "content", required = true) String content,
            @RequestParam(value = "imgs", required = false) List<String> imgs
    ) {
        Long SID = RsaUtil.parseSid(sid, privateKey);
        service.deleteImgs(tid, SID);
        service.commitContent(content, tid, SID);
        service.commitImgs(tid, SID, imgs);
        return new SampleResult<>("/task/post/task", HttpStatus.HTTP_OK, null, "提交成功");
    }

}